package com.nash.demands;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import org.ksoap2.serialization.SoapObject;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.TabActivity;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.BaseColumns;
import android.provider.Settings.Secure;
import android.text.method.PasswordTransformationMethod;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;

public class DemandsActivity extends TabActivity {

  public static final int CREATE_REQUEST_CODE = 0;
  public static final int EDIT_REQUEST_CODE = 1;
  public static final int VIEW_REQUEST_CODE = 2;
  public static final int SELECT_REQUEST_CODE = 3;
  public static final int POS_REQUEST_CODE = 4;

  public final static int UPDATE_STAGE_GET_VERSIONS = 1;
  public final static int UPDATE_STAGE_HOST = 2;
  public final static int UPDATE_STAGE_OSNR = 3;
  public final static int UPDATE_STAGE_ANSWER = 4;
  public final static int UPDATE_STAGE_GOODS = 5;
  public final static int UPDATE_STAGE_AGENT = 6;
  public final static int UPDATE_STAGE_TU_MAIN = 7;
  public final static int UPDATE_STAGE_TU_OSTATOK = 8;
  public final static int UPDATE_ERROR = 98;
  public final static int UPDATE_STAGE_FINISH = 99;

  public final static int SEND_STAGE_ORDERS = 1;
  public final static int SEND_ERROR = 98;
  public final static int SEND_STAGE_FINISH = 99;

  private String license = null;
  private int userId = 0;
  private TextView tvDate;
  public int mYear;
  public int mMonth;
  public int mDay;
  public static SQLiteDatabase db;
  public ArrayList<String> list1;
  public TabHost tabHost;
  static final int DATE_DIALOG_ID = 0;
  static final int UPDATE_DIALOG = 1;
  static final int SEND_DIALOG = 2;

  public OrdersActivity orderActivity;
  public RoutesActivity routesActivity;
  public AgentsActivity agentsActivity;

  private UpdateThread updateThread;
  private ProgressDialog updateDialog;
  public Transport transport = new Transport();
  private DemandsActivity app;
  public boolean adminMode;

  SendThread sendThread;
  ProgressDialog sendDialog;

  public int code2;

  private Menu mainmenu;

  @Override
  public void onDestroy() {
    CloseDatabase();
    super.onDestroy();
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    app = this;
    adminMode = false;
    boolean bStart = true;

    try {
      OpenDatabase();

      try {
        license = getOptionValue("LICENSE");
        userId = Integer.parseInt(getOptionValue("ID_ANSWER"));
      } catch (DemandsException e) {
        Helper.clearDb(db);
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle("Внимание");
        alert.setMessage("КПК не зарегистрирован. Введите лицензионный код.");

        final EditText input = new EditText(this);
        alert.setView(input);

        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {
            String s = input.getText().toString();
            registerLicense(s.trim(), 0);
          }
        });

        alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {
            finish();
          }
        });
        alert.show();
      } catch (java.lang.NumberFormatException e) {
        bStart = false;
        DemandsException.dialogError(this, e, true);
        try {
          Helper.clearDb(db);
        } catch (SQLException e2) {
          DemandsException.dialogError(this, e2, true);
        }
      } catch (Exception e) {
        bStart = false;
        DemandsException.dialogError(this, e, true);
      }
      if (bStart) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // Date
        tvDate = (TextView) findViewById(R.id.tvDate);
        final Calendar c = Calendar.getInstance();
        mYear = c.get(Calendar.YEAR);
        mMonth = c.get(Calendar.MONTH);
        mDay = c.get(Calendar.DAY_OF_MONTH);

        // display the current date (this method is below)
        updateDisplayDate();

        // Tabs
        Resources res = getResources();
        tabHost = getTabHost();
        TabHost.TabSpec spec;
        Intent intent;

        intent = new Intent().setClass(this, AgentsActivity.class);
        spec = tabHost.newTabSpec("agents").setIndicator("Точки", res.getDrawable(R.drawable.ic_tab_agents)).setContent(intent);

        tabHost.addTab(spec);

        intent = new Intent().setClass(this, RoutesActivity.class);
        spec = tabHost.newTabSpec("routes").setIndicator("Маршрут", res.getDrawable(R.drawable.ic_tab_routes)).setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(this, OrdersActivity.class);
        spec = tabHost.newTabSpec("orders").setIndicator("Заявки", res.getDrawable(R.drawable.ic_tab_orders)).setContent(intent);
        tabHost.addTab(spec);

        /*
         * intent = new Intent().setClass(this, StocksActivity.class); spec =
         * tabHost.newTabSpec("stock").setIndicator("Остатки",
         * res.getDrawable(R.drawable.ic_tab_stocks)).setContent(intent);
         * tabHost.addTab(spec);
         */

        tabHost.setCurrentTab(0);
      }
    } catch (SQLException e) {
      AlertDialog alertDialog = new AlertDialog.Builder(DemandsActivity.this).create();
      alertDialog.setTitle("Ошибка базы данных");
      alertDialog.setMessage(e.getLocalizedMessage());
      alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          finish();
        }
      });
      alertDialog.show();
    }

  }

  public void OpenDatabase() {
    Helper dbHelper = new Helper(DemandsActivity.this);
    db = dbHelper.getWritableDatabase();
  }

  public void CloseDatabase() {
    db.close();
  }

  private class FreeAnswers {
    int id;
    String name;

    public FreeAnswers(int pid, String pname) {
      id = pid;
      name = pname;
    }

    @Override
    public String toString() {
      return name;
    }
  }

  private void getFreeAnswers(final String newLicenses) throws DemandsException {

    String devId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
    SoapObject res = transport.LoadBySoap("getFreeAnswers", 0, devId, newLicenses, 0, null);
    // Vector<FreeAnswers> arr=new Vector<FreeAnswers>();
    ArrayList<FreeAnswers> arr = new ArrayList<FreeAnswers>();
    for (int i = 0, cnt = res.getPropertyCount(); i < cnt; i++) {
      SoapObject o = (SoapObject) res.getProperty(i);
      arr.add(new FreeAnswers(Integer.parseInt(o.getProperty("a").toString()), o.getProperty("b").toString()));
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Регистрация");

    final ArrayAdapter<FreeAnswers> aa = new ArrayAdapter<FreeAnswers>(this, android.R.layout.select_dialog_singlechoice, arr) {
      @Override
      public long getItemId(int position) {
        return this.getItem(position).id;
      }

    };

    final ListView lv = new ListView(this);
    lv.setAdapter(aa);
    builder.setCancelable(true);
    builder.setSingleChoiceItems(aa, -1, new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int item) {
        registerLicense(newLicenses, (int) (aa.getItem(item).id));
        dialog.dismiss();
      }
    });

    builder.show();

  }

  private void registerLicense(final String newLicense, final int answerId) {
    try {
      final String devId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
      try {
        SoapObject res1 = transport.LoadBySoap("registerLicense", 0, devId, newLicense, answerId, null);
        setOption("LICENSE", newLicense);
        userId = Integer.parseInt(((SoapObject) (res1.getProperty(0))).getProperty(1).toString());
        setOption("ID_ANSWER", ""+userId);
        license = newLicense;
        SoapObject res2 = transport.LoadBySoap("getOptions", 0, devId, license, userId, null);
        setOption("MAX_ID", (String) ((SoapObject) (res2.getProperty(0))).getProperty(1).toString());
        update();
      } catch (DemandsException e) {
        if (e.getCode() == DemandsException.SOAP_FAULT && e.getCode2() == DemandsException.SOAP_FAULT_LIC_USER_NOT_DEFINED) {
          getFreeAnswers(newLicense);
        } else {
          throw e;
        }
        return;
      }

    } catch (DemandsException e) {
      AlertDialog alertDialog = new AlertDialog.Builder(DemandsActivity.this).create();
      alertDialog.setTitle("Регистрация");
      alertDialog.setMessage("Нет такой лицензии, либо она уже используется.");
      alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          finish();
        }
      });
      alertDialog.show();
    }

  }

  @Override
  protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DATE_DIALOG_ID:
      return new DatePickerDialog(this, mDateSetListener, mYear, mMonth, mDay);
    case UPDATE_DIALOG:
      updateDialog = new ProgressDialog(DemandsActivity.this);
      updateDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      updateDialog.setMessage("Обновление данных");
      return updateDialog;
    case SEND_DIALOG:
      sendDialog = new ProgressDialog(DemandsActivity.this);
      sendDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      sendDialog.setMessage("Отправка заявок");
      return sendDialog;
    }
    return null;
  }

  @Override
  protected void onPrepareDialog(int id, Dialog dialog) {
    switch (id) {
    case UPDATE_DIALOG:
      updateDialog.setProgress(0);
      updateThread = new UpdateThread(handlerUpdate, this);
      updateThread.start();
      break;
    case SEND_DIALOG:
      sendDialog.setProgress(0);
      sendThread = new SendThread(handlerSend, this);
      sendThread.start();
      break;
    }

  }

  // the callback received when the user "sets" the date in the dialog
  private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
      mYear = year;
      mMonth = monthOfYear;
      mDay = dayOfMonth;
      updateDisplayDate();
      if (routesActivity != null)
        routesActivity.setAdapterRoutes();
      if (orderActivity != null)
        orderActivity.setAdapterOrders();
    }

  };

  private void updateDisplayDate() {
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    Calendar c = Calendar.getInstance();
    c.set(mYear, mMonth, mDay);
    tvDate.setText(new StringBuilder().append("Дата: ").append(sdf.format(c.getTime())));
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    this.mainmenu = menu;
    MenuInflater inflater = getMenuInflater();
    if (adminMode)
      inflater.inflate(R.menu.menu_admin, menu);
    else
      inflater.inflate(R.menu.menu, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
    case R.id.user_mode:
      DemandsActivity.this.adminMode = false;
      mainmenu.clear();
      DemandsActivity.this.getMenuInflater().inflate(R.menu.menu, mainmenu);
      Toast.makeText(DemandsActivity.this.getApplicationContext(), "Пользовательский режим", Toast.LENGTH_SHORT).show();
      return true;
    case R.id.admin_mode:
      AlertDialog.Builder alert = new AlertDialog.Builder(this);
      alert.setTitle("Администратор? Представьтесь...");
      final EditText input = new EditText(this);
      input.setTransformationMethod(new PasswordTransformationMethod());
      alert.setView(input);
      alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          String s = input.getText().toString();
          if (s.trim().toLowerCase().equals("gps")) {
            DemandsActivity.this.adminMode = true;
            mainmenu.clear();
            DemandsActivity.this.getMenuInflater().inflate(R.menu.menu_admin, mainmenu);
            Toast.makeText(DemandsActivity.this.getApplicationContext(), "Режим бога", Toast.LENGTH_SHORT).show();
          }
        }
      });

      alert.show();
      return true;
    case R.id.menu_clearDb:
      AlertDialog.Builder builder = new AlertDialog.Builder(this);
      builder.setMessage("Удалить регистрацию? Все данные будут утеряны.").setPositiveButton("Да", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          try {
            Helper.clearDb(db);
            finish();
          } catch (SQLException e) {
            DemandsException.dialogError(DemandsActivity.this, e, true);
          }
        }
      }).setNegativeButton("Нет", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          dialog.cancel();
        }
      });
      builder.show();
      return true;
    case R.id.menu_exit:
      this.finish();
      return true;
    case R.id.menu_refresh:
      update();
      return true;
    case R.id.menu_sendOrders:
      sendOrders();
      return true;
    case R.id.setDate:
      showDialog(DATE_DIALOG_ID);
      return true;
    case R.id.about:
      about();
      return true;
    default:
      return super.onOptionsItemSelected(item);
    }
  }

  private void about() {
    AlertDialog.Builder alert = new AlertDialog.Builder(this);

    Cursor c = DemandsActivity.db.query(Helper.TBL_ANSWER, new String[] { Helper.TBL_ANSWER_NAME + " as name" }, BaseColumns._ID + "=?", new String[] { "" + userId }, null, null, null);
    c.moveToFirst();
    String answerName = c.getString(c.getColumnIndex("name"));
    c.close();

    String ver = "";
    try {
      ver = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
    } catch (NameNotFoundException e) {
      e.printStackTrace();
    }
    alert.setMessage("Версия: " + ver + "\n" + answerName);

    alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int whichButton) {
      }
    });

    alert.show();

  }

  private void update() {
    try {
      showDialog(UPDATE_DIALOG);
    } catch (Exception e) {
      AlertDialog alertDialog;
      alertDialog = new AlertDialog.Builder(this).create();
      alertDialog.setTitle("Ошибка обновления");
      alertDialog.setMessage(e.getMessage());
      alertDialog.show();
    }
  }

  private void sendOrders() {
    try {
      showDialog(SEND_DIALOG);
    } catch (Exception e) {
      AlertDialog alertDialog;
      alertDialog = new AlertDialog.Builder(this).create();
      alertDialog.setTitle("Ошибка отправки");
      alertDialog.setMessage(e.getMessage());
      alertDialog.show();
    }
  }

  public final String getLicenseId() {
    return license;
  }

  public final int getUserId() {
    return userId;
  }

  public static String getOptionValue(final String name) throws DemandsException {
    String s = "select " + Helper.TBL_OPTIONS_VALUE + " from " + Helper.TBL_OPTIONS + " where " + Helper.TBL_OPTIONS_NAME + " = '" + name + "'";
    String ret = null;
    Cursor data = DemandsActivity.db.rawQuery(s, null);
    if (data.moveToFirst()) {
      ret = new String(data.getString(0));
    } else
      throw new DemandsException(DemandsException.EX_OPTIONS, DemandsException.EX_OPTIONS_NO_FOUND);
    if (!data.isClosed())
      data.close();
    return ret;
  }

  public static void setOption(final String name, final String value) {
    ContentValues cv = new ContentValues();
    cv.put(Helper.TBL_OPTIONS_NAME, name);
    cv.put(Helper.TBL_OPTIONS_VALUE, value);
    DemandsActivity.db.replace(Helper.TBL_OPTIONS, null, cv);
  }

  public final Handler handlerUpdate = new Handler() {
    public void handleMessage(Message msg) {
      // progressDialog.setProgress(msg.arg1);
      AlertDialog alertDialog;
      if (msg.arg1 == -1) {
        updateDialog.setProgress(0);
        updateDialog.setMax(1);
        switch (msg.arg2) {
        case UPDATE_STAGE_GET_VERSIONS:
          updateDialog.setMessage("Loading Versions...");
          break;
        case UPDATE_STAGE_HOST:
          updateDialog.setMessage("[1/7] Loading Host... ");
          break;
        case UPDATE_STAGE_OSNR:
          updateDialog.setMessage("[2/7] Loading Osnr... ");
          break;
        case UPDATE_STAGE_ANSWER:
          updateDialog.setMessage("[3/7] Loading Answer... ");
          break;
        case UPDATE_STAGE_GOODS:
          updateDialog.setMessage("[4/7] Loading Goods...");
          break;
        case UPDATE_STAGE_AGENT:
          updateDialog.setMessage("[5/7] Loading Agent... ");
          break;
        case UPDATE_STAGE_TU_MAIN:
          updateDialog.setMessage("[6/7] Loading TuMain... ");
          break;
        case UPDATE_STAGE_TU_OSTATOK:
          updateDialog.setMessage("[7/7] Loading TuStock... ");
          break;
        case UPDATE_ERROR:
          dismissDialog(UPDATE_DIALOG);
          updateThread.setState(UpdateThread.STATE_DONE);
          if (code2 == DemandsException.SOAP_FAULT_LIC_BAD || code2 == DemandsException.SOAP_FAULT_LIC_NOT_FOUND) {
            alertDialog = new AlertDialog.Builder(DemandsActivity.this).create();
            alertDialog.setTitle("Обновление");
            alertDialog.setMessage("Лицензия не зарегистрирована либо используется другим КПК");
            alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int whichButton) {
                dialog.cancel();
              }
            });
            alertDialog.show();
          } else {
            alertDialog = new AlertDialog.Builder(DemandsActivity.this).create();
            alertDialog.setTitle("Обновление");
            alertDialog.setMessage("Необработанная ошибка");
            alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int whichButton) {
                dialog.cancel();
              }
            });
            alertDialog.show();
          }
          break;
        case UPDATE_STAGE_FINISH:
          dismissDialog(UPDATE_DIALOG);
          updateThread.setState(UpdateThread.STATE_DONE);
          alertDialog = new AlertDialog.Builder(DemandsActivity.this).create();
          alertDialog.setTitle("Обновление");
          alertDialog.setMessage("Обновление успешно завершено");
          alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
              dialog.cancel();
            }
          });
          alertDialog.show();
          DemandsActivity.this.app.agentsActivity.setAdapterAgents();
          if (DemandsActivity.this.app.routesActivity != null)
            DemandsActivity.this.app.routesActivity.setAdapterRoutes();
          if (DemandsActivity.this.app.orderActivity != null)
            DemandsActivity.this.app.orderActivity.setAdapterOrders();
          break;
        }
      } else {
        updateDialog.setProgress(msg.arg1);
        updateDialog.setMax(msg.arg2 % 100000);
        switch (msg.arg2 / 100000) {
        case UPDATE_STAGE_HOST:
          updateDialog.setMessage("[1/7] Storing Host... ");
          break;
        case UPDATE_STAGE_OSNR:
          updateDialog.setMessage("[2/7] Storing Osnr... ");
          break;
        case UPDATE_STAGE_ANSWER:
          updateDialog.setMessage("[3/7] Storing Answer... ");
          break;
        case UPDATE_STAGE_GOODS:
          updateDialog.setMessage("[4/7] Storing Goods...");
          break;
        case UPDATE_STAGE_AGENT:
          updateDialog.setMessage("[5/7] Storing Agent... ");
          break;
        case UPDATE_STAGE_TU_MAIN:
          updateDialog.setMessage("[6/7] Storing TuMain... ");
          break;
        case UPDATE_STAGE_TU_OSTATOK:
          updateDialog.setMessage("[7/7] Storing TuOstatok... ");
          break;
        }
      }
    }
  };

  private final Handler handlerSend = new Handler() {
    AlertDialog alertDialog;

    public void handleMessage(Message msg) {
      // progressDialog.setProgress(msg.arg1);
      if (msg.arg1 == -1) {
        sendDialog.setProgress(0);
        sendDialog.setMax(1);
        switch (msg.arg2) {
        case SEND_STAGE_ORDERS:
          sendDialog.setMessage("Sending orders...");
          break;
        case SEND_ERROR:
          dismissDialog(SEND_DIALOG);
          sendThread.setState(SendThread.STATE_DONE);
          alertDialog = new AlertDialog.Builder(DemandsActivity.this).create();
          alertDialog.setTitle("Отправка");
          alertDialog.setMessage("При отправке заявок произошла ошибка");
          alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
              dialog.cancel();
            }
          });
          alertDialog.show();
          if (orderActivity != null)
            orderActivity.setAdapterOrders();
          break;
        case SEND_STAGE_FINISH:
          dismissDialog(SEND_DIALOG);
          sendThread.setState(SendThread.STATE_DONE);
          alertDialog = new AlertDialog.Builder(DemandsActivity.this).create();
          alertDialog.setTitle("Отправка заявок");
          alertDialog.setMessage("Успешно отправлено: " + (msg.what >> 8) + (((msg.what & 0xff) > 0) ? "\nНе передано: " + (msg.what & 0xff) : ""));
          alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
              dialog.cancel();
            }
          });
          alertDialog.show();
          if (orderActivity != null)
            orderActivity.setAdapterOrders();
          break;
        }
      } else {
        sendDialog.setProgress(msg.arg1);
        sendDialog.setMax(msg.arg2 % 100000);
        switch (msg.arg2 / 100000) {
        case SEND_STAGE_ORDERS:
          sendDialog.setMessage("Sending orders... ");
          break;
        }
      }
    }
  };

}
